import re

from django.core.validators import ValidationError

from ActionBase import ActionBase
from ActionExceptions import ActionIntegrityException
from Response import Response

from chat.model.Action import Action
from chat.model.User import User

class ActionChangeUsername(ActionBase):
    _action_token = 'nick'

    _USERNAME_REGEX = re.compile('^[A-Za-z0-9]*$')    
    _USERNAME_KEY = 'username'
    _USERNAME_MAX_LENGTH = 32
    
    _ERROR_NO_USERNAME          = 0x0001
    _ERROR_INVALID_USERNAME     = 0x0002
    _ERROR_DUPLICATE_USERNAME   = 0x0004

    def handle(self, postData):
        response = Response()
        
        username = postData.get(self._USERNAME_KEY, None)
        if username is None or len(username) == 0:
            response._status = self._ERROR_NO_USERNAME
            response._errors.append("No username specified.")
            return response
        
        if self._USERNAME_REGEX.match(username) is None or len(username) > self._USERNAME_MAX_LENGTH:
            response._status = self._ERROR_INVALID_USERNAME
            response._errors.append("Invalid username specified: Length must be less than %s and must contain only letters and numbers." % self._USERNAME_MAX_LENGTH)
            return response
        
        actionUser = User.verify_message(postData.get(self._USER_ID_TOKEN, None), postData.get(self._MESSAGE_KEY_TOKEN, None), postData.get(self._MESSAGE_HASH_TOKEN, None))
        if actionUser is None:
            raise ActionIntegrityException()
        old_username = actionUser.username
        
        try:
            actionUser.username = username
            actionUser.validate_unique()
            actionUser.save()
        except ValidationError:
            response._status = self._ERROR_DUPLICATE_USERNAME
            response._errors.append("Username currently in use.")
            return response

        for channel in actionUser.channels.all():
            self._log_action(actionUser, old_username, channel)
                    
        return response

    def _log_action(self, user, old_username, target):
        action = Action()
        action.action = 'NICK'
        action.username = user.username
        action.username_id = user.identity_id
        action.data = old_username
        action.target = target
        action.save()
